package com.jie.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jie.constants.RedisConstants;
import com.jie.constants.RedisCountConst;
import com.jie.dto.ActivityDTO;
import com.jie.dto.ActivityHotDTO;
import com.jie.entity.Activity;
import com.jie.entity.UserActivity;
import com.jie.exception.BizException;
import com.jie.mapper.ActivityMapper;
import com.jie.mapper.UserActivityMapper;
import com.jie.service.IActivityService;
import com.jie.utils.BeanCopyUtils;
import com.jie.utils.UserUtils;
import com.jie.vo.ActivityVo;
import com.jie.vo.ConditionVO;
import com.jie.vo.PageResult;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 热门活动表 服务实现类
 * </p>
 *
 * @author jie
 * @since 2024-04-24
 */

@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private HotRedisCountServiceImpl hotRedisCountService;
    @Autowired
    private UserActivityMapper userActivityMapper;
    /**
     * 查询活动列表
     * @param conditionVO
     * @return
     */
    @Override
    public PageResult<ActivityDTO> getActivityPageList(ConditionVO conditionVO) {
        conditionVO.setCurrent(conditionVO.getCurrent() > 0 ? conditionVO.getCurrent() : 1);
        conditionVO.setSize(conditionVO.getSize() > 0 ? conditionVO.getSize() : 10);
        Page<Activity> page = new Page<>(conditionVO.getCurrent(), conditionVO.getSize());
        // 查询日志列表
        Page<Activity> activityDTOPage = this.page(page, new LambdaQueryWrapper<Activity>()
                .like(StringUtils.isNotBlank(conditionVO.getKeywords()), Activity::getActivityName, conditionVO.getKeywords())
                .or()
                .like(StringUtils.isNotBlank(conditionVO.getKeywords()), Activity::getActivityInfo, conditionVO.getKeywords())
                .orderByDesc(Activity::getCreateTime));
        List<ActivityDTO> activityDTOList = BeanCopyUtils.copyList(activityDTOPage.getRecords(), ActivityDTO.class);
        return new PageResult<>(activityDTOList, (int) activityDTOPage.getTotal());
    }

    /**
     * 用户参与活动
     * @param activityId
     */
    @Override
    public void joinActivityInfo(Integer activityId) {
        //获取当前用户id
        Integer userId = UserUtils.getLoginUser().getId();
        //判断当前用户是否已经参与过
        SetOperations setOperations = redisTemplate.opsForSet();
        //获取当前活动信息
        Activity activity = this.baseMapper.selectById(activityId);
        if (Boolean.FALSE.equals(setOperations.isMember(RedisConstants.USER_ACTIVITY_LIST + activityId, userId))){
            //中间表存储一份做记录
            //因为子事务有aop 所以要采用代理对象调用方法
            ((ActivityServiceImpl) AopContext.currentProxy()).addActivityJoinUser(userId,activityId,activity);
            //redis存储一份
            setOperations.add(RedisConstants.USER_ACTIVITY_LIST + activityId, userId);
        }else {
            throw new BizException("请不要参加后卡bug继续参加");
        }

    }
    @Transactional(rollbackFor = Exception.class)
    @Async
    public void addActivityJoinUser(Integer userId, Integer activityId,Activity activity){
        //存入中间表 改为存入redis 做hash
        userActivityMapper.insert(UserActivity.builder().userId(userId).activityId(activityId).build());
        //计算排行版的次数
        hotRedisCountService.activityHotCount(activity);
    }

    /**
     * 根据redis获取热门排行版前十的活动
     * @return
     */
    @Override
    public List<ActivityHotDTO> activityHotPopularList() {
        return hotRedisCountService.getActivityHotCount();
    }

    /**
     * 活动参加人数
     * @param activityId
     * @return
     */
    @Override
    public ActivityDTO getActivityById(Integer activityId) {
        //获取当前activityId的统计数
        Activity activity = this.baseMapper.selectById(activityId);
        if(Objects.isNull(activity)){
            throw new BizException("活动不存在");
        }
        Long count = redisTemplate.opsForHyperLogLog().size(RedisCountConst.ACTIVITY_USER_COUNT+activityId);
        ActivityDTO activityDTO = BeanCopyUtils.copyObject(activity, ActivityDTO.class);
        activityDTO.setCount(count);
        return activityDTO;
    }

    @Override
    public boolean addActivityInfo(ActivityVo activityVo) {
        return false;
    }

    @Override
    public boolean updateActivityInfo(ActivityVo activityVo) {
        return false;
    }

    @Override
    public boolean deleteActivityInfo(Integer activityId) {
        return true;
    }

    @Override
    public boolean cancelLockActivityInfo(Integer activityId) {
        Integer userId = UserUtils.getLoginUser().getId();
        //删除中间表
        userActivityMapper.delete(new LambdaQueryWrapper<UserActivity>().eq(UserActivity::getActivityId,activityId)
                .eq(UserActivity::getUserId,userId));
        //删除redis
        redisTemplate.opsForSet().remove(RedisConstants.USER_ACTIVITY_LIST + activityId,userId);
        return true;
    }
}
